package com.yunshipei.common.net;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.yunshipei.base.BaseSubscriberAdapter;
import com.yunshipei.base.EnterBaseSubscriber;
import com.yunshipei.common.net.api.InterfaceApi;
import com.yunshipei.common.net.converter.JsonConverterFactory;
import com.yunshipei.core.common.XCloudException;
import com.yunshipei.core.net.EnterClient;
import com.yunshipei.model.AppConfigModel;
import com.yunshipei.model.CollectionData;
import com.yunshipei.model.FrequentContacts;
import com.yunshipei.model.ListAndGroup;
import com.yunshipei.model.ManagedSingleSignOn;
import com.yunshipei.model.UserInfo;
import com.yunshipei.ui.activity.DetailContactsActivity;

import org.json.JSONArray;
import org.json.JSONObject;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.rong.app.model.GroupCreateInfo;
import io.rong.app.utils.StringUtilSub;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class HttpMethods {

    private HttpMethods() {
    }

    private static class SingletonHolder {
        private static final HttpMethods INSTANCE = new HttpMethods();
    }

    public static HttpMethods getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private String mManagerServer = "";
    private InterfaceApi mJSONConverterApi;
    private InterfaceApi mGSONConverterApi;

    public void initManagerServer(String managerServer) {
        this.mManagerServer = managerServer;
        if (!TextUtils.isEmpty(managerServer)) {
            this.mJSONConverterApi = new Retrofit.Builder()
                    .client(EnterClient.getInstances().getManagerClient())
                    .addConverterFactory(JsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .baseUrl(managerServer)
                    .build().create(InterfaceApi.class);
            this.mGSONConverterApi = new Retrofit.Builder()
                    .client(EnterClient.getInstances().getManagerClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .baseUrl(managerServer)
                    .build().create(InterfaceApi.class);
        }
    }

    public String getManagerServer() {
        return mManagerServer;
    }

    //修改登录密码
    public void modifyPassword(String uuid, String password, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> observable = mJSONConverterApi.modifyPassword(uuid, password);
        toSubscribe(observable, subscriber);
    }

    //发送当前用户位置
    public void sendLocation(String devicesID, String address) {
        Flowable<JSONObject> observable = mJSONConverterApi.sendLocation(devicesID, address);
        toSubscribe(observable, new BaseSubscriberAdapter<JSONObject>());
    }

    //检测更新
    public void checkUpdate(String companyID, EnterBaseSubscriber subscriber) {
        Flowable<JSONObject> checkObservable = mJSONConverterApi.checkUpdate(companyID);
        toSubscribe(checkObservable, subscriber);
    }

    //签到
    public void checkIn(String beaconUuid, String major, String minor, String companyId, String name, EnterBaseSubscriber subscriber) {
        Flowable<JSONObject> checkInObservable = mJSONConverterApi.checkIn(beaconUuid, major, minor, companyId, name);
        toSubscribe(checkInObservable, subscriber);
    }

    //通过群组id获取群组消息
    public void fetchGroupById(String gid, EnterBaseSubscriber subscriber) {
        Flowable<JSONObject> fetchGroupObservable = mJSONConverterApi.fetchGroupById(gid);
        toSubscribe(fetchGroupObservable, subscriber);
    }

    //获取组织架构信息
    public void fetchDepartment(String id, String companyId, BaseSubscriberAdapter<FrequentContacts> subscriber) {
        Flowable<FrequentContacts> fetchDepartmentObservable = mGSONConverterApi.fetchDepartment(id, companyId);
        toSubscribe(fetchDepartmentObservable, subscriber);
    }

    //找回密码
    public void retrievePassword(String port, Map<String, String> map, BaseSubscriberAdapter<JSONObject> subscriber) {
        String url = mManagerServer + port;
        Flowable<JSONObject> retrievePasswordObservable = mJSONConverterApi.retrievePassword(url, map);
        toSubscribe(retrievePasswordObservable, subscriber);
    }

    //重新获取新群组信息
    public void reFetchGroupInfo(String uuid, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> reFetchGroupObservable = mJSONConverterApi.reFetchGroupInfo(uuid);
        reFetchGroupObservable.subscribe(subscriber);
    }

    //重新获取所有群组数据
    public Flowable<List<GroupCreateInfo>> allGroups(String uuid) {
        return mJSONConverterApi.reFetchGroupInfo(uuid).flatMap(new Function<JSONObject, Publisher<List<GroupCreateInfo>>>() {
            @Override
            public Publisher<List<GroupCreateInfo>> apply(JSONObject jsonObject) throws Exception {
                if (0 == jsonObject.optInt("status")) {
                    return Flowable.error(new XCloudException(jsonObject.optString("message", "未知接口异常...")));
                }
                JSONArray data = jsonObject.optJSONArray("data");
                List<GroupCreateInfo> groupInfos = new ArrayList<>();
                if (data != null) {
                    int length = data.length();
                    if (length > 0) {
                        for (int i = 0; i < length; i++) {
                            JSONObject object = data.optJSONObject(i);
                            if (object != null) {
                                GroupCreateInfo groupCreateInfo = StringUtilSub.SqlToObj(object);
                                groupInfos.add(groupCreateInfo);
                            }
                        }
                    }
                }
                return Flowable.just(groupInfos);
            }
        });
    }

    //获取通讯录列表
    public void fetchContactsList(String cid, String uuid, String password, BaseSubscriberAdapter<FrequentContacts> subscriber) {
        Flowable<FrequentContacts> fetchContactsObservable = mGSONConverterApi.fetchContactsList(cid, uuid, password);
        fetchContactsObservable.subscribe(subscriber);
    }

    //获取通讯录列表
    public Flowable<List<UserInfo>> allContacts(String cid, String uuid, String password) {
        return mGSONConverterApi.fetchContactsList(cid, uuid, password).flatMap(new Function<FrequentContacts, Publisher<List<UserInfo>>>() {
            @Override
            public Publisher<List<UserInfo>> apply(FrequentContacts frequentContacts) throws Exception {
                int status = frequentContacts.getStatus();
                if (0 == status) {
                    return Flowable.error(new XCloudException(frequentContacts.getMessage()));
                }
                List<UserInfo> userInfos = new ArrayList<>();
                ListAndGroup listAndGroup = frequentContacts.getData();
                if (listAndGroup != null) {
                    List<UserInfo> list = listAndGroup.getMembers();
                    userInfos.addAll(list);
                }
                return Flowable.just(userInfos);
            }
        });
    }


    //重新获取token
    public void reFetchToken(String uuid, EnterBaseSubscriber subscriber) {
        Flowable<JSONObject> reFetchTokenObservable = mJSONConverterApi.reFetchToken(uuid);
        toSubscribe(reFetchTokenObservable, subscriber);
    }

    //获取验证码
    public void fetchReCaptcha(String uuid, String content, EnterBaseSubscriber subscriber) {
        Flowable<JSONObject> reCaptchaObservable = mJSONConverterApi.fetchReCaptcha(uuid, content);
        toSubscribe(reCaptchaObservable, subscriber);
    }

    //获取群组成员
    public void addIMGroupMembers(String id, String name, String cIds, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> imGroupMembersObservable = mJSONConverterApi.addIMGroupMembers(id, name, cIds);
        toSubscribe(imGroupMembersObservable, subscriber);
    }

    //创建群组
    public void setupIMGroup(String cid, String gid, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> setupIMGroupObservable = mJSONConverterApi.makeIMGroup(cid, gid);
        toSubscribe(setupIMGroupObservable, subscriber);
    }

    //退出群组
    public void quitIMGroup(boolean isActive, String companyId, String quitUuid, String id, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> quitIMGroupObservable = mJSONConverterApi.exitIMGroup(isActive, companyId, quitUuid, id);
        toSubscribe(quitIMGroupObservable, subscriber);
    }

    //修改群组名称
    public void modifyIMGroupName(String gid, String name, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> modifyIMGroupNameObservable = mJSONConverterApi.modifyGroupName(gid, name);
        toSubscribe(modifyIMGroupNameObservable, subscriber);
    }

    //修改群组头像
    public void modifyIMGroupAvatar(String gid, File file, BaseSubscriberAdapter<JSONObject> subscriber) {
        Map<String, RequestBody> map = new HashMap<>();
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        RequestBody uuidBody = RequestBody.create(MediaType.parse("text/plain"), gid);
        map.put("gid", uuidBody);
        map.put("photo\"; filename=\"" + file.getName() + "\"", fileBody);
        Flowable<JSONObject> uploadFileObservable = mJSONConverterApi.modifyIMGroupAvatar(map);
        toSubscribe(uploadFileObservable, subscriber);
    }

    //修改个人头像
    public void modifyPersonalAvatar(File file, String uuid, BaseSubscriberAdapter<JSONObject> subscriber) {
        Map<String, RequestBody> map = new HashMap<>();
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        RequestBody uuidBody = RequestBody.create(MediaType.parse("text/plain"), uuid);
        map.put("uuid", uuidBody);
        map.put("photo\"; filename=\"" + file.getName() + "\"", fileBody);
        Flowable<JSONObject> uploadFileObservable = mJSONConverterApi.modifyPersonalAvatar(map);
        toSubscribe(uploadFileObservable, subscriber);
    }

    //修改个人头像
    public Flowable<JSONObject> modifyPersonalAvatar(File file, String uuid) {
        Map<String, RequestBody> map = new HashMap<>();
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        RequestBody uuidBody = RequestBody.create(MediaType.parse("text/plain"), uuid);
        map.put("uuid", uuidBody);
        map.put("photo\"; filename=\"" + file.getName() + "\"", fileBody);
        return mJSONConverterApi.modifyPersonalAvatar(map);
    }

    //添加常用联系人
    public void addColleague(String uuid, String targetUuid, String cid, DetailContactsActivity.AddColleagueSubscriber subscriber) {
        Flowable<JSONObject> addColleagueObservable = mJSONConverterApi.addColleague(uuid, targetUuid, cid);
        toSubscribe(addColleagueObservable, subscriber);
    }

    //删除常用联系人
    public void deleteColleague(String uuid, String targetUuid, String cid, EnterBaseSubscriber subscriber) {
        Flowable<JSONObject> deleteColleagueObservable = mJSONConverterApi.deleteColleague(uuid, targetUuid, cid);
        toSubscribe(deleteColleagueObservable, subscriber);
    }

    //应用再次激活，发送请求到服务端
    public void processRestart(String companyId, String name, String uuid) {
        Flowable<JSONObject> observable = mJSONConverterApi.processRestart(companyId, name, uuid);
        toSubscribe(observable, new BaseSubscriberAdapter<JSONObject>());
    }

    //获取常用联系人
    public void getColleagues(String companyId, String uuid, String departmentId, BaseSubscriberAdapter<FrequentContacts> subscriber) {
        Flowable<FrequentContacts> getColleaguesSubscriber = mGSONConverterApi.getColleagues(companyId, uuid, departmentId);
        toSubscribe(getColleaguesSubscriber, subscriber);
    }

    public void getUserInfoById(String companyId, String uuid, EnterBaseSubscriber subscriber) {
        Flowable<JSONObject> fetchGroupObservable = mJSONConverterApi.getUserInfo(companyId, uuid);
        toSubscribe(fetchGroupObservable, subscriber);
    }

    //退出群组
    public void newExitIMGroup(boolean isActive, String companyId, String[] uuids, String gid, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> quitIMGroupObservable = mJSONConverterApi.newExitIMGroup(isActive, companyId, uuids, gid);
        toSubscribe(quitIMGroupObservable, subscriber);
    }

    //添加收藏
    public void addCollection(String companyId, String uuid, String item, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> addCollectionObservable = mJSONConverterApi.addCollection(companyId, uuid, item);
        toSubscribe(addCollectionObservable, subscriber);
    }

    //删除收藏
    public void deleteCollection(String companyId, String uuid, String item, BaseSubscriberAdapter<JSONObject> subscriber) {
        Flowable<JSONObject> delCollectionObservable = mJSONConverterApi.deleteCollection(companyId, uuid, item);
        toSubscribe(delCollectionObservable, subscriber);
    }

    //获取收藏内容
    public void getCollection(String companyId, String uuid, BaseSubscriberAdapter<CollectionData> subscriber) {
        Flowable<CollectionData> getCollectionObservable = mGSONConverterApi.getCollectionList(companyId, uuid);
        toSubscribe(getCollectionObservable, subscriber);
    }

    //埋点信息处理
    public Flowable<JSONObject> pointsFlowable(String data) {
        return mJSONConverterApi.statisticData(data);
    }

    //获取sso相关
    public Flowable<ManagedSingleSignOn> ssoFlowable(String companyId, String userName, String password) {
        return mJSONConverterApi.getSingleSign(companyId, userName, password).flatMap(new Function<JSONObject, Publisher<ManagedSingleSignOn>>() {
            @Override
            public Publisher<ManagedSingleSignOn> apply(JSONObject jsonObject) throws Exception {
                int status = jsonObject.optInt("status");
                if (0 == status) {
                    return Flowable.error(new XCloudException(jsonObject.optString("message", "未知接口异常，请联系管理员")));
                }
                JSONObject data = jsonObject.optJSONObject("data");
                JSONObject ssoObject = null;
                if (data != null) {
                    ssoObject = data.optJSONObject("managedSingleSignOn");
                }
                if (ssoObject == null) {
                    return Flowable.error(new XCloudException("数据体为空，请联系管理员"));
                }
                Gson gson = new Gson();
                return Flowable.just(gson.fromJson(ssoObject.toString(), ManagedSingleSignOn.class));
            }
        });
    }

    //获取配置信息
    public Flowable<AppConfigModel.Data> getSetting(String companyId) {
        return mGSONConverterApi.getSetting(companyId).flatMap(new Function<AppConfigModel, Publisher<AppConfigModel.Data>>() {
            @Override
            public Publisher<AppConfigModel.Data> apply(AppConfigModel appConfigModel) throws Exception {
                if (0 == appConfigModel.status || appConfigModel.data == null) {
                    String message = appConfigModel.message;
                    return Flowable.error(new XCloudException(TextUtils.isEmpty(message) ? "未知接口异常，请联系管理员" : message));
                }
                return Flowable.just(appConfigModel.data);
            }
        });
    }

    //====================发布====================
    private <T> void toSubscribe(Flowable<T> o, Subscriber<T> s) {
        o.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s);
    }
}
